package level4.display
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	import level4.helpers.DictionaryHelper;
	import level4.interfaces.IGameDispose;
	import level4.interfaces.dispose.IDisposable;
	import level4.iso.IsoUtil;

	/**
	 * 可视化组件基类
	 * 推荐代替MovieClip,因为实现了自动卸载功能.
	 * 1 加入显示列表 调用init
	 * 2 从显示列表移除 调用deInit.
	 * 3 调用dispose,将去除事件和子类
	 * 
	 * 
	 * */
	public class GameDispose extends MovieClip implements IGameDispose,IDisposable
	{
		//统计外部调用new运算符的次数
		private static var instanceCounter:int;
		/**是否debug*/
		public var isDebug:Boolean = false;
		/**随机id*/
		public var gameDisposeId:int;
		//所有的监听器
		private var listenerDict:Dictionary = new Dictionary();
		//捕获阶段
		private var listenerDictCapture:Dictionary = new Dictionary();
		//记录下当前的容器
		private var originalParent:DisplayObjectContainer;
		
		public function GameDispose()
		{
			addEventListener(Event.ADDED_TO_STAGE,init);
			addEventListener(Event.REMOVED_FROM_STAGE,deInit);
			
			gameDisposeId = Math.random() * 100000;
			
			instanceCounter ++;
		}
		/**
		 * 绘制 一个小圆形
		 * @param gridX : int ,网格坐标x
		 * @param gridY:int,网格坐标y
		 * @param gridSize:int,网格大小
		 * */
		public function testDraw(gridX:int,gridY:int,gridSize:int):void{
			var pt:Point = IsoUtil.GridToScreen(new Point(gridX,gridY),gridSize);
			
			graphics.beginFill(0xffffff * Math.random());
			graphics.drawCircle(pt.x,pt.y,3);
			graphics.endFill();
		}
		/**
		 * 初始化工作
		 * 添加到舞台时调用
		 * */
		public function init(e:Event):void{
			if(isDebug)
				trace("super init");
//			addEventListener(Event.ENTER_FRAME,checkVisible);
			originalParent = parent;
		}
		/**
		 * 卸载工作
		 * 从舞台删除时调用
		 * */
		public function deInit(e:Event):void{
			if(isDebug)
				trace("super deinit");
		}
		/**
		 * 彻底销毁
		 * 去除自身的所有子类,事件.
		 * */
		public function dispose():void{
			if(parent){
				parent.removeChild(this);
			}
			removeAllEventListeners();
			removeAllChildren(this);
			DictionaryHelper.removeAllKeys(listenerDict);
			DictionaryHelper.removeAllKeys(listenerDictCapture);
			
			originalParent = null;
			instanceCounter --;
		}
		
		/**
		 * 删除全部的子类
		 * */
		public function removeAllChildren(container:DisplayObjectContainer = null):void{
			container = container == null ? this : container;
			while(container.numChildren != 0){
				 container.removeChildAt(0);
			}
		}
		
		/////////////////////
		//重写
		/////////////////////
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void{
			super.addEventListener(type,listener,useCapture,priority,useWeakReference);
			//添加
			var dict:Dictionary = listenerDict;
			if(useCapture)
				dict = listenerDictCapture;
			dict[listener] = type;
		}
		
		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void{
			super.removeEventListener(type,listener,useCapture);
			//清理
			var dict:Dictionary = listenerDict;
			if(useCapture)
				dict = listenerDictCapture;
			dict[listener] = null;
			delete dict[listener];
		}
		///////////////////////
		//公共方法
		///////////////////////
		/**
		 * 移除 已记录的所有的监听器,不过,闭包方式的监听还是无法移除
		 * 所以,添加监听时不要用闭包.
		 * */
		public function removeAllEventListeners():void{
			for(var k:* in listenerDict){
				removeEventListener(listenerDict[k],k);
			}
			for(k in listenerDictCapture)
				removeEventListener(listenerDictCapture[k],k);
		}
		/**
		 * 此对象,有没有此(listener)监听器?
		 * */
		public function hasThisListener(listener:Function,useCapture:Boolean=false):Boolean{
			var dict:Dictionary = listenerDict;
			if(useCapture)
				dict = listenerDictCapture;
			for(var k:* in dict){
				if(k == listener)
					return true;
			}
			return false;
		}
		/**
		 * 字符串形式
		 * */
		override public function toString():String{
//			var str:String = "children:"+numChildren+",events:{";
//			for(var k:Object in listenerDict){
//				str +="type:"+k+",listener:"+listenerDict[k]+"\n";
//			}
//			str +="}";
			var str:String = "GD{x:"+x+"}";
			return str; 
		}
		/**
		 * 获取 监听器的数量
		 * */
		public function get listenerCount():int{
			var count:int = 0;
			for(var k:Object in listenerDict){
				count ++;
			}
			return count;
		}
		/**
		 * 子显示对象的个数
		 * @return int
		 * */
		public function get childCount():int{
			return numChildren;
		}
		/**
		 * 获取 此类被实例化的个数.
		 * @return int.
		 * */
		public static function get InstanceCounter():int{
			return instanceCounter;
		}
		///////////////////////////////////////////
		//事件
		///////////////////////////////////////////
		private function checkVisible(e:Event):void{
			if(originalParent && originalParent.stage){
				var st:Stage = originalParent.stage;
				var selfRect:Rectangle = getRect(st);
				var globalRect:Rectangle = new Rectangle(0,0,st.stageWidth,st.stageHeight);
				if(selfRect.intersects(globalRect)){//显示
					originalParent.addChild(this);
				}else{//不显示
					if(parent){
						parent.removeChild(this);
						originalParent = parent;	
					}
				}
			}
		}
	}
}